﻿using System;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
using OF.Common;

namespace OF.Controls
{

    /// <summary>
    /// 文件名称：文本框控件
    /// </summary>
    [DefaultProperty("Text"), ToolboxData("<{0}:OFTextBox runat=server></{0}:OFTextBox>"), Designer("System.Web.UI.Design.WebControls.PreviewControlDesigner, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
    public class OFTextBox : TextBox, ISearcher
    {
        #region sql搜索条件接口的实现
        /// <summary>
        /// 获取或设置sql条件字段
        /// </summary>
        [Bindable(false), Category("Behavior"), DefaultValue(""), Description("获取或设置sql条件字段。")]
        public string SqlField
        {
            get
            {
                object o = ViewState["SqlField"];
                return (o == null) ? "" : o.ToString();
            }
            set
            {
                ViewState["SqlField"] = value;
            }
        }
        /// <summary>
        /// 获取或设置sql条件关系符
        /// </summary>
        [Bindable(false), Category("Behavior"), DefaultValue("等于"), TypeConverter(typeof(CharacterTypeConverter)), Description("获取或设置sql条件关系符。")]
        public string SqlCharacter
        {
            get
            {
                object o = ViewState["SqlCharacter"];
                return (o == null) ? "" : o.ToString();
            }
            set
            {
                ViewState["SqlCharacter"] = value;
            }
        }
        /// <summary>
        /// 获取搜索条件语句
        /// </summary>
        /// <returns></returns>
        public string GetSqlWhere()
        {
            string txt = Text.Trim();
            if (!string.IsNullOrWhiteSpace(txt))
            {
                string strWhere;
                switch (SqlCharacter)
                {
                    case "小于":
                        strWhere = SqlField + " < '" + txt + "'";
                        break;
                    case "等于":
                        strWhere = SqlField + " = '" + txt + "'";
                        break;
                    case "大于":
                        strWhere = SqlField + " > '" + txt + "'";
                        break;
                    case "小于等于":
                        strWhere = SqlField + " <= '" + txt + "'";
                        break;
                    case "大于等于":
                        strWhere = SqlField + " >= '" + txt + "'";
                        break;
                    case "不等于":
                        strWhere = SqlField + " <> '" + txt + "'";
                        break;
                    case "包含":
                        strWhere = SqlField + " like '%" + txt + "%'";
                        break;
                    case "开始":
                        strWhere = SqlField + " like '" + txt + "%'";
                        break;
                    case "结束":
                        strWhere = SqlField + " like '%" + txt + "'";
                        break;
                    case "存在于":
                        strWhere = SqlField + " in (" + txt + ")";
                        break;
                    default:
                        strWhere = SqlField + " = '" + txt + "'";
                        break;
                }

                return strWhere;
            }
            return "";
        }
        /// <summary>
        /// 获取当前控件的ID
        /// </summary>
        /// <returns></returns>
        public string GetControlId()
        {
            return ID;
        }
        /// <summary>
        /// 获取或设置搜索分组
        /// </summary>
        [Bindable(false), Category("Behavior"), DefaultValue(""), Description("获取或设置sql搜索分组。")]
        public string SearcherGroupName
        {
            get
            {
                object o = ViewState["SearcherGroupName"];
                return (o == null) ? "" : o.ToString();
            }
            set
            {
                ViewState["SearcherGroupName"] = value;
            }
        }
        #endregion

        #region 过滤
        
        /// <summary>
        /// 是否文本使用过滤器
        /// </summary>
        [Browsable(true), Themeable(true), Category("Behavior"), DefaultValue(true), Description("是否文本使用过滤器")]
        public bool UseFilter
        {
            get
            {
                object o = ViewState["useFilter"];
                if (o != null)
                {
                    bool useFilter = Utils.ToBool(o, true);
                    return useFilter;
                }
                return true;
            }
            set
            {
                ViewState["useFilter"] = value;
            }
        }

        #endregion

        #region 验证信息

        /// <summary>
        /// 控件提示名称
        /// </summary>
        [Browsable(true), Themeable(true), Category("Behavior"), DefaultValue(false), Description("控件提示名称")]
        public string ToolName
        {
            get
            {
                object o = ViewState["ToolName"];
                if (o != null)
                {
                    return o.ToString();
                }
                return "";
            }
            set
            {
                ViewState["ToolName"] = value;
            }
        }

        /// <summary>
        /// 验证信息显示的目标控件ID
        /// </summary>
        [Bindable(false), Category("Behavior"), DefaultValue(""), TypeConverter(typeof(FormControlsConverter)), Description("验证信息显示的目标控件ID。")]
        public string ValidMessagePanel
        {
            get
            {
                object o = ViewState["errorPanel"];
                if (o != null)
                {
                    return o.ToString();
                }
                return "";
            }
            set
            {
                ViewState["errorPanel"] = value;
            }
        }

        private string GetErrorMessage(string ctlName, string msg)
        {
            string m = string.IsNullOrWhiteSpace(ctlName) ? msg : ctlName + " " + msg;
            return m;
        }

        private void AddToErrorPanel(BaseValidator validator)
        {
            if (!string.IsNullOrWhiteSpace(ValidMessagePanel))
            {
                Control ctlContainer = this.Parent;
                Panel panel = null;
                while (ctlContainer != null)
                {
                    panel = ctlContainer.FindControl(ValidMessagePanel) as Panel;
                    if (panel != null)
                        break;
                    ctlContainer = ctlContainer.Parent;
                }
                if (panel == null)
                {
                    panel = Page.FindControl(ValidMessagePanel) as Panel;
                }
                if (panel != null)
                {
                    panel.Controls.Add(validator);
                }
            }
            else
            {
                this.Controls.Add(validator);
            }
        }

        #endregion

        #region 验证控件

        /// <summary>
        /// RequiredFieldValidator控件变量
        /// </summary>
        protected RequiredFieldValidator canBeNullRfv = new RequiredFieldValidator();

        /// <summary>
        /// RegularExpressionValidator控件变量
        /// </summary>
        protected RegularExpressionValidator requiredFieldTypeRev = new RegularExpressionValidator();

        /// <summary>
        /// RangeValidator控件变量
        /// </summary>
        protected RangeValidator numberRv = new RangeValidator();

        #endregion

        #region  验证属性

        /// <summary>
        /// 要进行校验的类型
        /// </summary>
        [Bindable(false), Category("Behavior"), DefaultValue(""), TypeConverter(typeof(RequiredFieldTypeControlsConverter)), Description("要进行校验的类型。")]
        public string RequiredFieldType
        {
            get
            {
                object o = ViewState["RequiredFieldType"];
                return (o == null) ? "" : o.ToString();
            }
            set
            {
                ViewState["RequiredFieldType"] = value;
            }
        }
        /// <summary>
        /// 要表达式是否可以为空
        /// </summary>
        [Bindable(false), Category("Behavior"), DefaultValue("可为空"), TypeConverter(typeof(CanBeNullControlsConverter)), Description("要表达式是否可以为空。")]
        public string CanBeNull
        {
            get
            {
                object o = ViewState["CanBeNull"];
                return (o == null) ? "" : o.ToString();
            }
            set
            {
                ViewState["CanBeNull"] = value;
            }
        }
        /// <summary>
        /// 有效校验表达式
        /// </summary>
        [Bindable(true), Category("Appearance"), DefaultValue(""), Description("有效校验表达式。")]
        public string ValidationExpression
        {
            get
            {
                object o = ViewState["ValidationExpression"];
                if (o == null || o.ToString().Trim() == "")
                {
                    return null;
                }
                return o.ToString().ToLower();
            }
            set
            {
                ViewState["ValidationExpression"] = value;
            }
        }
        /// <summary>
        /// 要表达式是否可以为空
        /// </summary>
        [Bindable(false), Category("Behavior"), DefaultValue("false"), Description("是否可以自定义错误输出信息")]
        public string CanCustomMsg
        {
            get
            {
                object o = ViewState["CanCustomMsg"];
                return (o == null) ? "" : o.ToString();
            }
            set
            {
                ViewState["CanCustomMsg"] = value;
            }
        }
        /// <summary>
        /// 最小值属性
        /// </summary>
        [Bindable(true), Category("Appearance"), DefaultValue(null), Description("最小值属性。")]
        public string MaximumValue { get; set; }
        /// <summary>
        /// 最大值属性
        /// </summary>
        [Bindable(true), Category("Appearance"), DefaultValue(null), Description("最大值属性。")]
        public string MinimumValue { get; set; }

        #endregion

        /// <summary>
        /// 构造函数
        /// </summary>
        public OFTextBox()
        {
            MinimumValue = null;
            MaximumValue = null;
            Size = 30;
        }

        /// <summary>
        /// 添加属性方法
        /// </summary>
        /// <param name="key">键值,如class等</param>
        /// <param name="valuestr">要绑定的字符串</param>
        public void AddAttributes(string key, string valuestr)
        {
            Attributes.Add(key, valuestr);
        }

        /// <summary>
        /// 创建子控件
        /// </summary>
        protected override void CreateChildControls()
        {
            //当指定了输入框的最小或最大值时,则加入校验范围项
            if (MaximumValue != null || MinimumValue != null)
            {
                numberRv.ControlToValidate = ID;
                numberRv.Type = ValidationDataType.Double;
                numberRv.Display = ValidatorDisplay.Dynamic;
                numberRv.CssClass = "error";

                if (MaximumValue != null && this.MinimumValue != null)
                {
                    numberRv.MaximumValue = this.MaximumValue;
                    numberRv.MinimumValue = this.MinimumValue;
                    numberRv.ErrorMessage = ToolName + "输入数据应在" + this.MinimumValue + "和" + this.MaximumValue + "之间!";
                }
                else
                {
                    if (MaximumValue != null)
                    {
                        numberRv.MaximumValue = this.MaximumValue;
                        numberRv.MinimumValue = Int32.MinValue.ToString();
                        numberRv.ErrorMessage = ToolName + "输入数据允许最大值为" + this.MaximumValue;
                    }
                    if (this.MinimumValue != null)
                    {
                        numberRv.MinimumValue = this.MinimumValue;
                        numberRv.MaximumValue = Int32.MaxValue.ToString();
                        numberRv.ErrorMessage = ToolName + "输入数据允许最小值为" + this.MinimumValue;
                    }
                }

                AddToErrorPanel(numberRv);
            }

            if ((!string.IsNullOrEmpty(RequiredFieldType)) && (RequiredFieldType != "暂无校验"))
            {
                requiredFieldTypeRev.Display = ValidatorDisplay.Dynamic;
                requiredFieldTypeRev.ControlToValidate = this.ID;
                requiredFieldTypeRev.CssClass = "error";
                switch (RequiredFieldType)
                {
                    case "数据校验":
                        {
                            requiredFieldTypeRev.ValidationExpression = this.ValidationExpression ?? "^[-]?\\d+[.]?\\d*$";
                            requiredFieldTypeRev.ErrorMessage = GetErrorMessage(ToolName, "数字格式不正确!"); break;
                        }
                    case "电子邮箱":
                        {
                            requiredFieldTypeRev.ValidationExpression = this.ValidationExpression ?? (@"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");
                            requiredFieldTypeRev.ErrorMessage = GetErrorMessage(ToolName, "邮箱格式不正确!"); break;
                        }
                    case "移动手机":
                        {
                            requiredFieldTypeRev.ValidationExpression = this.ValidationExpression ?? "\\d{11}";
                            requiredFieldTypeRev.ErrorMessage = GetErrorMessage(ToolName, "手机格式不正确!"); break;
                        }
                    case "家用电话":
                        {
                            // "((\\(\\d{3}\\) ?)|(\\d{3}-))?\\d{3}-\\d{4}|((\\(\\d{3}\\) ?)|(\\d{4}-))?\\d{4}-\\d{4}"
                            // 前台会员中心验证：^(\d{3,4}-\d{7,8})|(1[3458]\d{9})$
                            requiredFieldTypeRev.ValidationExpression = this.ValidationExpression ??"^(\\d{3,4}-\\d{7,8})|(1[3458]\\d{9})$";
                            requiredFieldTypeRev.ErrorMessage = GetErrorMessage(ToolName, "电话格式不正确!"); break;
                        }
                    case "身份证号码":
                        {
                            requiredFieldTypeRev.ValidationExpression = this.ValidationExpression ?? "^\\d{15}$|^\\d{18}$";
                            requiredFieldTypeRev.ErrorMessage = GetErrorMessage(ToolName, "身份证格式不正确!"); break;
                        }
                    case "网页地址":
                        {
                           requiredFieldTypeRev.ValidationExpression = this.ValidationExpression ?? @"^(http|https)\://([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&%\$\-]+)*@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{1,10}))(\:[0-9]+)*(/($|[a-zA-Z0-9\.\,\?\'\\\+&%\$#\=~_\-]+))*$";
                           // requiredFieldTypeRev.ValidationExpression = this.ValidationExpression ?? @"^(http(s)?:\/\/)?(www\.)?[\w-]+\.\w{2,4}(\/)?$";
                           // requiredFieldTypeRev.ValidationExpression = this.ValidationExpression ?? @"^(http(s)?:\/\/)?(www\.)?[\w-]+\.\w{2,4}?(\.\w{2,4})?$";
                            requiredFieldTypeRev.ErrorMessage = GetErrorMessage(ToolName, "网址格式不正确!"); break;
                        }
                    case "日期":
                        {
                            requiredFieldTypeRev.ValidationExpression = this.ValidationExpression ?? @"^((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-9]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-))$";
                            requiredFieldTypeRev.ErrorMessage = GetErrorMessage(ToolName, "日期格式不正确!"); break;
                        }
                    case "日期时间":
                        {
                            requiredFieldTypeRev.ValidationExpression = this.ValidationExpression ?? @"^((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-9]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-)) (20|21|22|23|[0-1]?\d)(:[0-5]?\d){0,2}$";
                            requiredFieldTypeRev.ErrorMessage = GetErrorMessage(ToolName, "时间格式不正确!"); break;
                        }
                    case "金额":
                        {
                            requiredFieldTypeRev.ValidationExpression = this.ValidationExpression ?? "^([0-9]|[0-9].[0-9]{0-2}|[1-9][0-9]*.[0-9]{0,2})$";
                            requiredFieldTypeRev.ErrorMessage = GetErrorMessage(ToolName, "金额格式不正确!"); break;
                        }
                    case "IP地址":
                        {
                            requiredFieldTypeRev.ValidationExpression = this.ValidationExpression ?? @"^(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])$";
                            requiredFieldTypeRev.ErrorMessage = GetErrorMessage(ToolName, "IP地址格式不正确!"); break;
                        }
                    case "IP地址带端口":
                        {
                            requiredFieldTypeRev.ValidationExpression = this.ValidationExpression ?? @"^(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9]):\d{1,5}?$";
                            requiredFieldTypeRev.ErrorMessage = GetErrorMessage(ToolName, "IP端口格式格式不正确!"); break;
                        }
                    case "QQ":
                        {
                            requiredFieldTypeRev.ValidationExpression = this.ValidationExpression ?? "^[1-9]\\d{4,11}$";
                            requiredFieldTypeRev.ErrorMessage = GetErrorMessage(ToolName, "QQ只能为5-12位数字!"); break;
                        }
                    case "自定义验证":
                        {
                            requiredFieldTypeRev.ValidationExpression = this.ValidationExpression;
                            requiredFieldTypeRev.ErrorMessage = GetErrorMessage(ToolName, "格式不正确!"); break;
                        }
                }

                AddToErrorPanel(requiredFieldTypeRev);
            }

            switch (CanBeNull)
            {
                case "可为空": { break; }
                case "必填":
                    {
                        canBeNullRfv.Display = ValidatorDisplay.Dynamic;
                        canBeNullRfv.ControlToValidate = this.ID;
                        canBeNullRfv.CssClass = "error";
                        if (CanCustomMsg == "true")
                        {
                            canBeNullRfv.ErrorMessage = ToolName;
                        }
                        else
                        {
                            canBeNullRfv.ErrorMessage = ToolName + "未填写内容!";
                        }
                        AddToErrorPanel(canBeNullRfv);
                        break;
                    }
                default: { break; }
            }

        }

        /// <summary>
        /// 获取焦点的控件ID(如提交按钮等)
        /// </summary>
        [Bindable(true), Category("Appearance"), DefaultValue(""), Description("获取焦点的控件ID(如提交按钮等)")]
        public string SetFocusButtonId
        {
            get
            {
                object o = ViewState[this.ClientID + "_SetFocusButtonID"];
                return (o == null) ? "" : o.ToString();
            }
            set
            {
                ViewState[this.ClientID + "_SetFocusButtonID"] = value;
                if (value != "")
                {
                    this.Attributes.Add("onkeydown", "if(event.keyCode==13){document.getElementById('" + value + "').focus();}");
                }
            }
        }

        /// <summary>
        /// 控件的最大长度属性
        /// </summary>
        [Bindable(true), Category("Appearance"), DefaultValue(""), Description("控件的最大长度属性")]
        public override int MaxLength
        {
            get
            {
                object o = ViewState["TextBox_MaxLength"];
                if (o != null)
                {
                    int maxlength = Utils.ToInt(o.ToString(), 4);
                    AddAttributes("maxlength", maxlength.ToString());
                    return maxlength;
                }
                return -1;
            }
            set
            {
                ViewState["TextBox_MaxLength"] = value;
                AddAttributes("maxlength", value.ToString());
            }
        }

        /// <summary>
        /// 控件的TextMode属性
        /// </summary>
        [Bindable(false), Category("Behavior"), DefaultValue(TextBoxMode.SingleLine), Description("控件的TextMode属性。")]
        public override TextBoxMode TextMode
        {
            get
            {
                return base.TextMode;
            }
            set
            {
                if (value == TextBoxMode.MultiLine)
                {
                    Attributes.Add("onkeyup", "return isMaxLen(this)");
                }

                base.TextMode = value;
            }
        }

        /// <summary>
        /// 文本内容属性
        /// </summary>
        [Bindable(true), Category("Appearance"), DefaultValue(""), Description("文本内容属性。")]
        public override string Text
        {
            get
            {
                //进行强制日期格式的转换
                if (RequiredFieldType == "日期")
                {
                    try
                    {
                        return DateTime.Parse(base.Text).ToString("yyyy-MM-dd");
                    }
                    catch
                    {
                        return "";
                    }
                }

                //进行强制日期时间格式的转换
                if (RequiredFieldType == "日期时间")
                {
                    try
                    {
                        return DateTime.Parse(base.Text).ToString("yyyy-MM-dd HH:mm:ss");
                    }
                    catch
                    {
                        return "";
                    }
                }
                return base.Text;
            }
            set
            {
                //进行强制日期格式的转换
                if (RequiredFieldType.IndexOf("日期", StringComparison.Ordinal) >= 0)
                {
                    try
                    {
                        base.Text = DateTime.Parse(value).ToString("yyyy-MM-dd");
                    }
                    catch
                    {
                        base.Text = "";
                    }
                }

                //进行强制日期时间格式的转换
                if (RequiredFieldType.IndexOf("日期时间", StringComparison.Ordinal) >= 0)
                {
                    try
                    {
                        base.Text = DateTime.Parse(value).ToString("yyyy-MM-dd HH:mm:ss");
                    }
                    catch
                    {
                        base.Text = "";
                    }
                }
                else
                {
                    if (UseFilter)
                    {
                        value = SqlKey.CheckWord(value);
                    }
                    base.Text = value;
                }
            }
        }

        /// <summary>
        /// 宽度属性
        /// </summary>
        [Bindable(true), Category("Appearance"), DefaultValue(30), Description("宽度属性。")]
        public int Size { get; set; }

        /// <summary> 
        /// 输出html,在浏览器中显示控件
        /// </summary>
        /// <param name="output"> 要写出到的 HTML 编写器 </param>
        protected override void Render(HtmlTextWriter output)
        {

            //当为TextArea时，maxlength属性可能失效，所以采用js进行长度限制
            if (TextMode == TextBoxMode.MultiLine)
            {
                output.WriteLine("<script type=\"text/javascript\">");
                output.WriteLine("function isMaxLen(o){");
                output.WriteLine("var nMaxLen=o.getAttribute? parseInt(o.getAttribute(\"maxlength\")):\"\";");
                output.WriteLine(" if(o.getAttribute && o.value.length>nMaxLen){");
                output.WriteLine(" o.value=o.value.substring(0,nMaxLen)");
                output.WriteLine("}}</script>");
            }
            else if (TextMode == TextBoxMode.Password)
            {
                AddAttributes("value", this.Text);
                AddAttributes("class", "ipt");
            }
            else
            {
                if (Size > 0)
                {
                    AddAttributes("size", Size.ToString());
                }
                AddAttributes("class", "ipt");
            }

            base.Render(output);

            if (string.IsNullOrWhiteSpace(ValidMessagePanel))
            {
                RenderChildren(output);
            }
        }
    }
}
